package com.example.websocketdemo.websocket;

import com.example.websocketdemo.pojo.ServerMongodb;
import com.example.websocketdemo.websocketConfig.EncoderClassVo;
import com.example.websocketdemo.websocketConfig.MessageConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * TODO  websocket 测试类
 *       需求：定时向前端传输数据（）不用理会前端传过来的数据
 *
 * @ClassName GMessageListener
 * @Author xiaojiang
 * @Date 2021/9/29 下午 18:07
 */
@ServerEndpoint(value = "/websocket",
        configurator = MessageConfigurator.class,
        encoders = {EncoderClassVo.class})
@Component
public class GMessageListener {

    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;

    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话，可以使用Map来存放，其中Key可以为用户标识
    //public static ConcurrentMap<String, UserSession> webSocketSet = new ConcurrentHashMap<>();

    private static CopyOnWriteArraySet<GMessageListener> webSocketSet = new CopyOnWriteArraySet<GMessageListener>();
    private static Logger logger = LoggerFactory.getLogger(GMessageListener.class);

    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
    private Timer timer = new Timer();

    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        System.out.println("session+++++++" + session);
        webSocketSet.add(this);     //加入set中
        addOnlineCount();//在线数加1
        System.out.println("有新连接加入！当前在线人数为" + getOnlineCount());
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                // task to run goes here
                try {
                    if (getOnlineCount() != 0) {

                        sendMessage();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (EncodeException e) {
                    e.printStackTrace();
                }
                System.out.println("Hello !!!");
            }
        };

        long delay = 0;
        long intevalPeriod = 2 * 1000;
        // schedules the task to be run in an interval
        this.timer.scheduleAtFixedRate(task, delay, intevalPeriod);
    }

    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  //从set中删除
        subOnlineCount();           //在线数减1

        System.out.println("有一连接关闭！当前在线人数为" + getOnlineCount());
    }

    @OnMessage
    public void pongMessage(Session session, String message) {
        System.out.println("来自客户端的消息:" + message);
    }


    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();

        logger.error(error.getMessage());
    }

    /**
     * 这个方法与上面几个方法不一样。没有用注解，是根据自己需要添加的方法，返回给前端数据。
     */
    public void sendMessage() throws IOException, EncodeException {

        List<Map> li = new ArrayList<>();
        Map mapp = new HashMap();
        // mongodb定义
        // 会话数
        Long U1 = 0L;
        Long D1 = 0L;
        Long U2 = 0L;
        Long D2 = 0L;
        Long U3 = 0L;
        Long D3 = 0L;
        Long U4 = 0L;
        Long D4 = 0L;

        Map map = new HashMap();
        System.out.println("-------------------------------执行到这一步");

        map.put("ip_address", "192.168.1.1");
        map.put("server_name", "测试机器");
        ServerMongodb u =new ServerMongodb();
        u.setU1(11111L);
        u.setD1(222222L);
        u.setU2(33333L);
        u.setD2(44444L);
        u.setU3(66666L);
        u.setD3(77777L);
        u.setU4(99999L);
        u.setD4(10101L);

        map.put("ServerMongodb", u);
        li.add(map);
        if (li.size() != 0) {
            System.out.println("mapp>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + mapp);

            mapp.put("U1", 220000);
            mapp.put("D1", 220000);
            mapp.put("U2", 3713423855L); // shangxing
            mapp.put("D2", 18492447416L); // xiaxing
            mapp.put("T2", 22205871271L); // tuntuliang
            mapp.put("U3", 3602021139L);  // 上行
            mapp.put("D3", 17013051622L); // 下行
            mapp.put("T3", 20615072761L); // 吞吐量
            mapp.put("U4", 99999);
            mapp.put("D4", 101010);
            mapp.put("U5", 121212);
            mapp.put("D5", 131313);
            mapp.put("U6", 0);
            mapp.put("D6", 0.00000014);
            mapp.put("U8", 161616);
            mapp.put("D8", 171717);
            mapp.put("U9", 181818);
            mapp.put("D9", 191919);
            mapp.put("T9", 202020);

            li.add(mapp);
        }
        session.getBasicRemote().sendObject(li);
    }


    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        GMessageListener.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        GMessageListener.onlineCount--;
    }


    public static void main(String[] args) {
        String imsi = "460000010000001";
        String random = "ewr55t5yu5i14";
        byte[] data = (imsi + "/" + random + "+" + "2").getBytes(StandardCharsets.UTF_8);
        DatagramSocket datagramSocket = null;
        try {
            // 实例化套接字，并指定发送端口
            datagramSocket = new DatagramSocket();
            // 指定数据目的地的地址，以及目标端口
            InetAddress destination = InetAddress.getByName("127.0.0.1");
            DatagramPacket datagramPacket = new DatagramPacket(data, data.length, destination, 40100);
            // 发送数据
            datagramSocket.send(datagramPacket);

            logger.info("发送AMF2停止,消息已发送=");
        } catch (SocketException e) {
            logger.info("AMF2停止 消息发送失败=", e);

        } catch (IOException e) {
            logger.info("AMF2停止 消息发送失败-", e);
        } finally {
            datagramSocket.close();
        }
    }



}
